/**
 * <p>Copyright (c) 2017 深圳市鹏途交通科技有限公司</p>
 * <p>					All right reserved. 		 </p>
 * <p>项目名称 ： 	深圳市道路养护管理系统        </p>
 * <p>创建者   :	 刘波波 
 * <p>描   述  :     </p>
 */
package com.pengtu.service.test2;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;

import java.text.ParseException;
import java.text.SimpleDateFormat;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.pengtu.entity.VehicleInfo;


/**
 * @author 刘波波
 * @date  2017/4/7
 * @describe handler处理类
 */
@Sharable//注解@Sharable可以让它在channels间共享
public class SimpleServerHandler extends ChannelInboundHandlerAdapter {
	@Autowired
	private VehicleInfoManager vehicleInfoManager;
	private int count = 2;
	
	/**
	 *@author 刘波波
	 *@date 2017年4月11日
	 *@describe 
	 */
	public SimpleServerHandler(VehicleInfoManager vehicleInfoManager) {
		super();
		this.vehicleInfoManager = vehicleInfoManager;
	}

	/**
	 *@author 刘波波
	 *@date 2017年4月11日
	 *@describe 
	 */
	public SimpleServerHandler() {
		super();
	}

	public static String toStringHex1(String s) {  
		byte[] baKeyword = new byte[s.length() / 2];
		for (int i = 0; i < baKeyword.length; i++) {
			try {
				baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		try {
			s = new String(baKeyword, "ASCII");
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		return s;
	}
	
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {
//		Object mg = ReferenceCountUtil.retain(msg);
		
		if(count == 1){System.out.println("SimpleServerHandler.....1111111"); 
		System.out.println("msg"+msg);
		ByteBuf result = (ByteBuf) ReferenceCountUtil.retain(msg); 
//		ByteBuffer buf = ByteBuffer.allocate(1024);
	    byte[] result1 = new byte[result.readableBytes()];
	    result.readBytes(result1); 
	    System.out.println("result1"+result1.length);
		System.out.println(new String(result1));
//		result.resetReaderIndex();
//	    byte[] result3 = new byte[result.readableBytes()];
//	    result.readBytes(result3); 
//	    System.out.println("result3"+result3.length);
//	    System.out.println(new String(result3));
		ctx.fireChannelRead(msg);
			//反馈数据报长度为定长13个字节
			String head = "AAAA";
			String end = "EEEE";
			String u = "4142433132330000";
			String p = "4142433132330000";
			String deviceNo = "30333131313733313037353531363037";
			String returnresult = "290009" + deviceNo + u + p + "E107041101000F00";
			String crcString = returnresult.substring(4);
			//crc验证得16进制验证码字符串
			CRC16M crc1 = new CRC16M();
			//16进制字符串转字节数组用于得到其crc验证码
			String hexString1 = crc1.getCRCString(crcString);
			String responseData = head + crcString + hexString1 + end;
			//帧头+内容+crc验证码+帧尾
			byte[] bts = new byte[responseData.length()];
			//16进制字符串转10进制字节数组
			bts = ByteTransformer.hexString2Bytes(responseData);
		    ByteBuf encoded = ctx.alloc().buffer(4 * bts.length);  
		    encoded.writeBytes(bts);
		    ctx.write(encoded);
		    ctx.flush();
		}else{
			System.out.println("SimpleServerHandler.....");
		VehicleInfo vehicleInfo = new VehicleInfo();
	    ByteBuf result = (ByteBuf) msg;  
	    byte[] result1 = new byte[result.readableBytes()];
	    result.readBytes(result1); 
	    //msg中存储的是ByteBuf类型的数据，把数据读取到byte[]中  
	    if (result1 == null || result1.length <= 0) {      
	
	    }
	    String[] str = new String[result1.length];
	    for (int i = 0; i < result1.length; i++) {
	        int v = result1[i] & 0xFF;       
	        String hv = Integer.toHexString(v);       
	        if (hv.length() < 2) {       
	            str[i] = "0";
	            str[i] += hv;
	        }else{
	        	str[i] = hv; 
	        }
	               
	    }
	    for (int i = 0; i < str.length; i++) {
			System.out.print(str[i] + " ");
		}
	    String crcString = "";
	    for(int i = 2; i < str.length-4; i++){
	    	crcString += str[i];
	    }
	    //crc验证得16进制验证码字符串
		CRC16M crc1 = new CRC16M();
		//16进制字符串转字节数组用于得到其crc验证码
		String hexString1 = crc1.getCRCString(crcString);
		if(!hexString1.equals(str[str.length - 4] + str[str.length - 3])) {
			System.out.println("crc验证不通过");
			//反馈数据报长度为定长13个字节
			int datalength = 13;
			String head = "AAAA";
			String end = "EEEE";
			String returnresult = "05000A" + str[43] + str[44] + "1201";
			//crc验证得16进制验证码字符串
			CRC16M crc = new CRC16M();
			//16进制字符串转字节数组用于得到其crc验证码
			byte[] bytes = ByteTransformer.hexString2Bytes(returnresult);
			crc.update(bytes, bytes.length);
			String hexString = Integer.toHexString(crc.getValue());
			
			//帧头+内容+crc验证码+帧尾
			byte[] bts = new byte[datalength];
			String responseData = head + returnresult + hexString + end;
			//16进制字符串转10进制字节数组
			bts =ByteTransformer.hexString2Bytes(responseData);
		    //释放资源，这行很关键  
//		    result.release();
		    //在当前场景下，发送的数据必须转换成ByteBuf数组  
		    ByteBuf encoded = ctx.alloc().buffer(4 * bts.length);  
		    encoded.writeBytes(bts);  
		    ctx.write(encoded);  
		    ctx.flush();
			
		}else{
			System.out.println("crc验证通过");
		
		//数据包类型
		vehicleInfo.setPacketType(str[4]);
		//设备身份识别码
		String deviceNumber = "";
		for(int i = 5; i < 21; i++){
			 String s = SimpleServerHandler.toStringHex1(str[i]);
			 deviceNumber += s;
		if(i == 7 || i == 9 || i == 11 || i == 12){
			 deviceNumber += " "; 
		}
		}
		vehicleInfo.setDeviceNumber(deviceNumber);
//		System.out.println("deviceNumber:" + deviceNumber);
		//站点编号
		String siteNumber = "";
		for(int i = 21;i < 36;i++){
			String s = SimpleServerHandler.toStringHex1(str[i]);
			siteNumber += s;
		}
		if(StringUtils.isNotBlank(siteNumber)) {
			siteNumber = siteNumber.trim();
		}
		vehicleInfo.setSiteNumber(siteNumber);
//		System.out.println("siteNumber:" + siteNumber);
		//设备硬件错误码
		vehicleInfo.setDeviceErrorNumber(str[36]);
		//调查内容
		vehicleInfo.setSurveyContent(str[37]);
		//数据生成日期 年 月 日
		String year = str[39] + str[38];
		year = Integer.parseInt(year,16) + "";
		String month = Integer.parseInt(str[40], 16) + "";
		String day = Integer.parseInt(str[41], 16) + "";
		System.out.println(year + "-" + month + "-" + day);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		vehicleInfo.setSendDate(sdf.parse(year + "-" + month + "-" + day));
		//交通数据处理周期，默认5分钟，可以由dsc控制
		vehicleInfo.setPeriodTime(Integer.parseInt(str[42], 16) + "");
		//（周期）时间序号
		vehicleInfo.setSerialNumber(Integer.parseInt(str[44] + str[43], 16) + "");
		//车道数
		vehicleInfo.setTrackNumber(Integer.parseInt(str[45], 16) + "");
		int cnum = Integer.parseInt(str[45], 16);
		for(int a = 0; a<cnum; a++) {
		    int b = a*32;
		//车道号
		vehicleInfo.setLaneNumber(Integer.parseInt(str[46 + b], 16) + "");
		//跟车百分比
		vehicleInfo.setPercentage(Integer.parseInt(str[47 + b], 16) + "");
		//平均车头间距
		vehicleInfo.setAverageCarDistance(Integer.parseInt(str[49 + b] + str[48 + b], 16) + "");
		//时间占有率
		vehicleInfo.setTimeRate(Integer.parseInt(str[50 + b], 16) + "");
		//中小客车交通量
		vehicleInfo.setMsPassengerTraffic(Integer.parseInt(str[52 + b] + str[51 + b], 16) + "");
		//中小客车平均地点车速
		vehicleInfo.setMsPassengerSpeed(Integer.parseInt(str[53 + b], 16)+ "");
		//小型货车交通量
		vehicleInfo.setsTruckTraffic(Integer.parseInt(str[55 + b] + str[54 + b], 16) + "");
		//小型货车平均地点车速   
		vehicleInfo.setsTruckSpeed(Integer.parseInt(str[56 + b], 16)+"");
		//大客车交通量
		vehicleInfo.setbPassengerTraffic(Integer.parseInt(str[55 + b] + str[54 + b], 16) + "");
		//大客车平均地点车速
		vehicleInfo.setbPassengerSpeed(Integer.parseInt(str[56 + b], 16) + "");
		//中型货车交通量
		vehicleInfo.setmTruckTraffic(Integer.parseInt(str[55 + b] + str[54 + b], 16) + "");
		//中型货车平均地点车速
		vehicleInfo.setmTruckSpeed(Integer.parseInt(str[56 + b], 16) + "");
		//大型货车交通量
		vehicleInfo.setbTruckTraffic(Integer.parseInt(str[58 + b] + str[57 + b], 16) + "");
		//大型货车平均地点车速
		vehicleInfo.setbTruckSpeed(Integer.parseInt(str[59 + b], 16) + "");
		//特大型货车交通量
		vehicleInfo.setElTruckTraffic(Integer.parseInt(str[61 + b] + str[60 + b], 16) + "");
		//特大型货车平均地点车速
		vehicleInfo.setElTruckSpeed(Integer.parseInt(str[62 + b], 16) + "");
		//集装箱车交通量
		vehicleInfo.setContainerCarTraffic(Integer.parseInt(str[64 + b] + str[63 + b], 16) + "");
		//集装箱车平均地点车速
		vehicleInfo.setContainerCarSpeed(Integer.parseInt(str[65 + b], 16) + "");
		//拖拉机交通量
		vehicleInfo.setTractorTraffic(Integer.parseInt(str[67 + b] + str[66 + b], 16) + "");
		//拖拉机平均地点车速
		vehicleInfo.setTractorSpeed(Integer.parseInt(str[68 + b], 16) + "");
		//摩托车交通量
		vehicleInfo.setMotorcycleTraffic(Integer.parseInt(str[70 + b] + str[69 + b], 16) + "");
		//摩托车平均地点车速
		vehicleInfo.setMotorcycleSpeed(Integer.parseInt(str[71 + b], 16) + "");
		
		vehicleInfoManager.saveOrUpdate(vehicleInfo);
		//反馈数据报长度为定长13个字节
		int datalength = 13;
		String head = "AAAA";
		String end = "EEEE";
		String returnresult = "05000A" + str[43] + str[44] + "FFFF";
		
		//crc验证得16进制验证码字符串
		CRC16M crc = new CRC16M();
		//16进制字符串转字节数组用于得到其crc验证码
		byte[] bytes = ByteTransformer.hexString2Bytes(returnresult);
		crc.update(bytes, bytes.length);
		String hexString = Integer.toHexString(crc.getValue());
		
		//帧头+内容+crc验证码+帧尾
		byte[] bts = new byte[datalength];
		String responseData = head + returnresult + hexString + end;
		//16进制字符串转10进制字节数组
		bts = ByteTransformer.hexString2Bytes(responseData);
	    //释放资源，这行很关键  
//	    result.release();
	    //在当前场景下，发送的数据必须转换成ByteBuf数组  
	    ByteBuf encoded = ctx.alloc().buffer(4 * bts.length);  
	    encoded.writeBytes(bts);  
	    ctx.write(encoded);  
	    ctx.flush();
	    }
		}
		}
	}
	
	public static void main(String[] args) throws ParseException {
		String[] str = {"0F","00"};
		int datalength = 13;
		String head = "AAAA";
		String end = "EEEE";
		String returnresult = "05000A"+str[0] + str[1]+"FFFF";
		
		//crc验证得16进制验证码字符串
		CRC16M crc = new CRC16M();
		//16进制字符串转字节数组用于得到其crc验证码
		byte[] bytes = ByteTransformer.hexString2Bytes(returnresult);
		crc.update(bytes, bytes.length);
		String hexString = Integer.toHexString(crc.getValue());
		
		//帧头+内容+crc验证码+帧尾
		byte[] bts = new byte[datalength];
		String responseData = head + returnresult + hexString+ end;
		//16进制字符串转10进制字节数组
		bts =ByteTransformer.hexString2Bytes(responseData);
		for(byte b1 : bts) {
			System.out.print(b1+" ");
		}
		//反向验证测试
		System.out.println();
		String[] strs = ByteTransformer.to16Strbytes(bts);
		for (int i = 0; i < strs.length; i++) {
			System.out.print(strs[i]+" ");
		}
		
	}

	public VehicleInfoManager getVehicleInfoManager() {
		return vehicleInfoManager;
	}

	public void setVehicleInfoManager(VehicleInfoManager vehicleInfoManager) {
		this.vehicleInfoManager = vehicleInfoManager;
	}

//	/**
//	 *@author 刘波波
//	 *@date 2017年5月16日
//	 *@describe 
//	 */
//	@Override
//	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
//			throws Exception {
//		cause.printStackTrace();
//		System.out.println("客户端关闭:"+ctx.channel().id());
////		InetSocketAddress sa = (InetSocketAddress) ctx.channel().remoteAddress();
//		ctx.channel().close();
//		ctx.close();
//	}

	/**
	 *@author 刘波波
	 *@date 2017年5月16日
	 *@describe 
	 */
	@Override
	public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
		// TODO Auto-generated method stub
		super.channelRegistered(ctx);
	}

	/**
	 *@author 刘波波
	 *@date 2017年5月16日
	 *@describe 
	 */
	@Override
	public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
		// TODO Auto-generated method stub
		super.channelUnregistered(ctx);
	}

	/**
	 *@author 刘波波
	 *@date 2017年5月16日
	 *@describe 
	 */
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		// TODO Auto-generated method stub
		super.channelActive(ctx);
	}

	/**
	 *@author 刘波波
	 *@date 2017年5月16日
	 *@describe 
	 */
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		// TODO Auto-generated method stub
		super.channelInactive(ctx);
	}


}
